<?php
/*
 * Copyright (C) 2010 TopCoder Inc., All Rights Reserved.
 */
namespace protocol\translation\framework\services\base;

use protocol\translation\framework\services\ConversionException;
use protocol\translation\framework\services\Helper;
use protocol\translation\framework\services\MissingMandatoryParametersException;

/**
 * <p>
 * The json convertor for the MM7 protocol.
 * </p>
 *
 * <p>
 * Thread Safety: This class is immutable and thread-safe.
 * </p>
 *
 * @author hpana, akinwale
 * @version 1.0
 */
class MM7_JSON_Converter implements Converter {
    /**
     * <p>
     * Represents the Logger instance to be used for logging.
     * </p>
     *
     * @var Logger
     */
    private static $LOGGER;

    /**
     * <p>
     * Represents a mapping of operation names to a list of required parameters for the MM7
     * JSON converter.
     * </p>
     *
     * @var array
     */
    private static $REQUIRED_PARAMS_MAP = array(
        Helper::SEND_SMS => array("address", "senderAddress", "message", Helper::CLIENT_CORRELATOR,
            Helper::NOTIFY_URL, "senderName"),
        Helper::SUB_DELIV_NOTI => array(Helper::NOTIFY_URL, Helper::CALLBACK_DATA),
        Helper::SUB_NOTI => array("destinationAddress", Helper::NOTIFY_URL, "criteria",
            "notificationFormat", Helper::CALLBACK_DATA, Helper::CLIENT_CORRELATOR),
        Helper::QUERY_DELIV_STATUS => array(),
        Helper::STOP_SUB_DELIV_NOTI => array(),
        Helper::RETRIEVE_MSGS_SENT => array(),
        Helper::STOP_SUB => array()
    );

    /**
     * <p>
     * Default constructor. Creates a new instance.
     * </p>
     */
    public function __construct() {
        self::$LOGGER = \Logger::getLogger(__CLASS__);
    }

    /**
     * <p>
     * This method is used to convert the protocol response to a format that can be used by the frontend.
     * </p>
     *
     * @param array $protocolMessage the response from the protocol message
     * @param string $operation this represents the OneAPI operation type also refered to as method
     *                   name because each service method implements one OneAPI protocol operation
     *
     * @return string the converted response
     *
     * @throws IllegalArgumentException if any argument is unset, protocolMessage is not of array type or
     *             if any array element is unset or if operation is an empty string or not of string type
     *             or not supported
     * @throws ConversionException if any other error occurs
     */
    public function convertTo($protocolMessage, $operation) {
        $startTime = microtime();
        $methodName = __CLASS__ . "#convertTo";
        Helper::logEntry($methodName, array("\$protocolMessage" => $protocolMessage, "\$operation" => $operation),
            self::$LOGGER);

        Helper::checkArray($protocolMessage, "\$protocolMessage", $methodName, self::$LOGGER);
        Helper::checkOperation($operation, self::$REQUIRED_PARAMS_MAP, $methodName, self::$LOGGER);

        $ret = json_encode($protocolMessage);
        Helper::logExit($methodName, $ret, $startTime, self::$LOGGER);
        return $ret;
    }

    /**
     * <p>
     * This method is used to convert from the requeset message body to an array of values to
     * be used for calling the dependent protocol.
     * </p>
     *
     * @param string $messageBody the request message body from which to extract the array of
     *                  parameters for calling the protocol
     * @param string $operation this represents the OneAPI operation type also refered to as method
     *                   name because each service method implements one OneAPI protocol operation
     *
     * @return array the array of parameters for calling the protocol
     *
     * @throws IllegalArgumentException if any argument is unset, empty string or not of string type
     *             of if operation is not supported
     * @throws MissingMandatoryParametersException if required parameters are missing
     * @throws ConversionException if any other error occurs
     */
    public function convertFrom($messageBody, $operation) {
        $startTime = microtime();
        $methodName = __CLASS__ . "#convertFrom";
        Helper::logEntry($methodName, array("\$messageBody" => $messageBody, "\$operation" => $operation),
            self::$LOGGER);

        Helper::checkString($messageBody, "\$messageBody", $methodName, self::$LOGGER);
        Helper::checkOperation($operation, self::$REQUIRED_PARAMS_MAP, $methodName, self::$LOGGER);

        $parsedBody = Helper::parseMessageBody($messageBody, $methodName, self::$LOGGER);

        // Validate the mandatory parameters
        $reqParamList = self::$REQUIRED_PARAMS_MAP[$operation];
        $keys = array_keys($parsedBody);
        foreach ($reqParamList as $reqParamKey) {
            if (!in_array($reqParamKey, $keys)) {
                throw Helper::logError($methodName, new MissingMandatoryParametersException(
                    "The param key [$reqParamKey] is required for the method name [$operation]"), self::$LOGGER);
            }
        }

        Helper::logExit($methodName, $parsedBody, $startTime, self::$LOGGER);
        return $parsedBody;
    }
}

?>